﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DiscoveryLogic.UI.Layouts.Controls;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.Collections.ObjectModel;
using System.Windows.Controls.Primitives;
using DiscoveryLogic.UI.Layouts.Converters;
using DiscoveryLogic.UI.Layouts.DataAcccesses;
using DiscoveryLogic.DataServices.DataSources;
using System.Windows.Data;


namespace DiscoveryLogic.UI.Layouts.ContentScreens
{
    public partial class TradeHistory : UserControl , IContentScreen
    {
        #region Private Variables

            

            private const int itemCount = 10;
            List<Trade> source = new List<Trade>();
            ObservableCollection<Trade> ocsource = new ObservableCollection<Trade>();

            private bool initialGridBind = true;
            private bool filteringForCompany = false;
            private bool tradeMarkerHighlighting = false;

            StockChart stockChart;

            DashboardForm parentContainer;

            TradeHistoryManager tradeHistoryManager;

        #endregion


            #region Constructors

            public TradeHistory(DashboardForm container)
            {
                tradeHistoryManager = new TradeHistoryManager();

                InitializeComponent();

                tradeHistoryManager.PropertyChanged += tradeHistoryManager_PropertyChanged;

                // The checkboxes are databound to the trade history manager so that they can directly affect the items
                // in the news list box and the news markers on the stock chart
                WorldWideCheckBox.DataContext = tradeHistoryManager;
                IndustryCheckBox.DataContext = tradeHistoryManager;
                CompanyCheckBox.DataContext = tradeHistoryManager;
                TrivialCheckBox.DataContext = tradeHistoryManager;

                parentContainer = container;

                // Attach handlers
                this.ViewAllTradesButton.Click += new RoutedEventHandler(OnViewAllTradesButton_Click);

                // Load data for news pane and trades chart
                LoadData();

                // Create dummy data for line chart
                DateTime[] dates = new DateTime[10];
                double[] prices = new double[10];

                // Dummy dates
                for (int i = 0; i < 10; i++)
                {
                    dates[i] = DateTime.Today.AddDays(-i * 15);
                }

                // Dummy prices
                prices[9] = 49;
                prices[8] = 70;
                prices[7] = 39;
                prices[6] = 26;
                prices[5] = 45;
                prices[4] = 20;
                prices[3] = 30;
                prices[2] = 50;
                prices[1] = 40;
                prices[0] = 70;

                // Create and position line chart
                stockChart = new StockChart(dates, prices, source, parentContainer, ref tradeHistoryManager);
                stockChart.SetValue(Canvas.TopProperty, 160.0);
                stockChart.SetValue(Canvas.LeftProperty, 50.0);

                // Add to canvas
                Root.Children.Add(stockChart);

                // The following two delegates are called by stock chart when one of the
                // trade markers on the chart on mouse entered/leaved
                stockChart.callTradeHistoryTradeMarkerEnter = ChartTradeMarker_Enter;
                stockChart.callTradeHistoryTradeMarkerLeave = ChartTradeMarker_Leave;

                // Binding the NewsList to the TradeHistory manager enables it to populate its list with the filtered news
                // The filtered news is affected by the check boxes for news types above the list, and also data binds
                // the SelectedIndex property which causes news markers in the stock chart to become visible / select items
                // in the listbox
                NewsList.DataContext = tradeHistoryManager;

                double value = 50000;
                TotalValueBox.Text = value.ToCurrency();

                value = 34.50;
                AvgPriceEnterLabel.Text = value.ToCurrency();

                value = 59.88;
                AvgPriceExitLabel.Text = value.ToCurrency();

                value = 10000;
                ProfitLossLabel.Text = value.ToCurrency();
            }

        #endregion

        #region IContentScreen Members

            public void ScreenShowActions()
            {
            //    throw new NotImplementedException();
            }

            public void ScreenHideActions()
            {
              //   throw new NotImplementedException();
            }
        #endregion

        #region Helper Methods

            private void LoadData()
            {
                // Load trades
                source = tradeHistoryManager.GetTrades();

                for (int i = 0; i < source.Count; i++)
                {
                    ocsource.Add(source[i]);
                }

                

                grid1.DataContext = null;
                initialGridBind = true;
                grid1.DataContext = ocsource;
                grid1.SelectedItem = null;
                grid1.ItemsSource = ocsource;
                // Set maximum property value of news list vertical scrollbar
                SetNewsPaneScrollBar(300);
            }

            /// <summary>
            /// Set the properties of the news pane scroll bar given the height.
            /// Properties such as Maximum and Viewport size is set based on how 
            /// much it needs to scroll.
            /// Also detects if scroll bar isn't needed. If not then visibility is set
            /// to collapsed.
            /// </summary>
            /// <param name="scrollBarHeight"></param>
            private void SetNewsPaneScrollBar(double scrollBarHeight)
            {
                // Change scroll bar
                this.NewsList.Height = scrollBarHeight;
            }

        #endregion

        #region Event Handlers

            /// <summary>
            /// On the view all button being clicked,
            /// repopulate the trades grid with all trades
            /// and hide the extra info panel
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnViewAllTradesButton_Click(object sender, RoutedEventArgs e)
            {
                // Reset bool variables
                filteringForCompany = false;                

                // Set data source of grid to original
                ObservableCollection<Trade> tempSource = new ObservableCollection<Trade>();

                for (int i = 0; i < source.Count; i++)
                {
                    tempSource.Add(source[i]);
                }
                grid1.DataContext = null;                
                initialGridBind = true;

                grid1.DataContext = tempSource;
                grid1.ItemsSource = null;
                grid1.ItemsSource = tempSource;
                // Set to no selected row
                grid1.SelectedItem = null;

                // Change label and extra information panel
                TradeGridLabel.Text = "Trades";

                //TradesPanelExtraInfo.Opacity = 0;
                TradesPanelExtraInfo.SetValue(Canvas.ZIndexProperty, 0);
                //grid1.Height = 200;
                //TradeGridRoot.SetValue(Canvas.TopProperty, 350);

                // Hide company info pane
                //CompanyPane.Visibility = Visibility.Collapsed;
                //CompanyPane.Opacity = 0;

                // Reposition news pane
                //NewsPane.SetValue(Canvas.TopProperty, 159);

                FullNewsListView.Begin();

                

                // Hide any company overlays
                stockChart.ToggleCompanyOverlay(false);

                // Draw all trade markers on the chart instead of only company specific ones
                stockChart.UpperChartTradeList = source;
                stockChart.RedrawTradeMarkers();
            }

            /// <summary>
            /// When a row in the trades panel is selected
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void grid1_SelectionChanged(object sender, EventArgs e)
            {
                Trade selectedTrade = (Trade)grid1.SelectedItem;

                // If this item is selected because user hovered over a trade
                // marker on the chart then don't do anything
                if (tradeMarkerHighlighting)
                {
                    tradeMarkerHighlighting = false;
                    return;
                }

                // If this is the initial binding of the grid
                // or we're drilling down to find only trades of a specific company
                // or no row selected, then exit
                if (initialGridBind || filteringForCompany || selectedTrade == null)
                {
                    initialGridBind = false;

                    if (filteringForCompany && selectedTrade != null)
                    {
                        stockChart.FindTradeMarker(selectedTrade.Id, selectedTrade.IsBuy);
                    }

                    return;
                }

                // Find only trades from that company                
              

                ObservableCollection<Trade> tempSource = new ObservableCollection<Trade>();
                List<Trade> tempSourceList = new List<Trade>();

                for (int i = 0; i < source.Count; i++)
                {
                    if (source[i].Symbol == selectedTrade.Symbol)
                    {
                        tempSource.Add(source[i]);
                        tempSourceList.Add(source[i]);
                        // Depending on whether its a buy or sell,
                        // increment either totalPriceEnter or totalPriceExit
                    }
                }

                filteringForCompany = true;
                grid1.DataContext = tempSource;
                grid1.ItemsSource = tempSource;
                grid1.SelectedItem = null;                                

                // Change label and extra information panel
                TradeGridLabel.Text = string.Format((string)Resources["Res_TradesGridLabel"], selectedTrade.Symbol);

                TradesPanelExtraInfo.SetValue(Canvas.ZIndexProperty, 2);
                //TradesPanelExtraInfo.Opacity = 1;
                //grid1.Height = 142;
                //TradeGridRoot.SetValue(Canvas.TopProperty, 380);

                // Show company info pane
                //CompanyPane.Visibility = Visibility.Visible;
                CompanyPaneNameLabel.Text = selectedTrade.Name + " (" + selectedTrade.Symbol + ")";
                
                // Reposition news pane
                //NewsPane.SetValue(Canvas.TopProperty, 335);

                // Change end point of opacity mask for news pane
                Point opacityEndPoint = new Point(NewsPaneOpacityBrush.EndPoint.X, 165.6);
                NewsPaneOpacityBrush.EndPoint = opacityEndPoint;

                CompanyView.Begin();

                // Change scroll bar
                SetNewsPaneScrollBar(150);
                
                // Show company overlays
                stockChart.ToggleCompanyOverlay(true);

                // Change the trade indicators on the chart
                stockChart.UpperChartTradeList = tempSourceList;
                stockChart.RedrawTradeMarkers();
            }

            /// <summary>
            /// When a user hovers over a trade marker on the stock chart
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ChartTradeMarker_Enter(object sender, MouseEventArgs e)
            {
                TradeHistoryTradeMarker marker = (TradeHistoryTradeMarker)sender;

                int targetId = marker.Id;
                bool targetIsBuy = marker.IsBuy;
                ObservableCollection<Trade> temp = (ObservableCollection<Trade>)grid1.DataContext;

                for (int i = 0; i < temp.Count; i++)
                {
                    if (temp[i].Id == targetId && temp[i].IsBuy == targetIsBuy)
                    {
                        tradeMarkerHighlighting = true;
                        grid1.SelectedItem = temp[i];
                        
                        break;
                    }
                }
            }

            /// <summary>
            /// When a user's mouse leaves a trade marker on the stock chart
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ChartTradeMarker_Leave(object sender, MouseEventArgs e)
            {                
                tradeMarkerHighlighting = true;
                grid1.SelectedItem = null;
            }


            void tradeHistoryManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                if (e.PropertyName == "SelectedNewsIndex" && tradeHistoryManager.SelectedNewsIndex > -1)
                    NewsList.ScrollIntoView(NewsList.Items[tradeHistoryManager.SelectedNewsIndex]);
            }
            
        #endregion

            private void FullNewsListView_Completed(object sender, EventArgs e)
            {
                if ((double)NewsPane.GetValue(Canvas.TopProperty) == 159)
                {
                    // Reset end point of opacity mask for news pane
                    Point opacityEndPoint = new Point(NewsPaneOpacityBrush.EndPoint.X, 322.608);
                    NewsPaneOpacityBrush.EndPoint = opacityEndPoint;

                    // Reset news pane vertical scroll bar
                    SetNewsPaneScrollBar(300);
                }
            }

        
            /// <summary>
            /// When animation of drilling down into a company is complete.
            /// That animation is started when the user clicks a row in the grid.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void CompanyView_Completed(object sender, EventArgs e)
            {
                // Change scroll bar
                SetNewsPaneScrollBar(150);
            }

    }

    public class UpDownConverter : System.Windows.Data.IValueConverter
    {

        #region IValueConverter Members

            /// <summary>
            /// Return the angle for the trade indicator in column 1 of trade grid
            /// </summary>
            /// <param name="value"></param>
            /// <param name="targetType"></param>
            /// <param name="parameter"></param>
            /// <param name="culture"></param>
            /// <returns></returns>
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                Trade d = value as Trade;
                if (d != null)
                {
                    if (d.IsBuy)
                    {
                        //return new BitmapImage(new Uri("../images/up.png", UriKind.Relative));
                        return "180";
                    }
                    else
                        //return new BitmapImage(new Uri("../images/down.png", UriKind.Relative));
                        return "0";
                }
                return null;
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }

        #endregion
    }


    public class Trade : IComparable, INotifyPropertyChanged
    {
            private int id;

            public int Id
            {
                get { return id; }
                set { id = value; }
            }

            private string name;

            public string Name
            {
                get { return name; }
                set { name = value; }
            }

            private string symbol;

            public string Symbol
            {
                get { return symbol; }
                set { symbol = value; }
            }

            private double price;

            public double Price
            {
                get { return price; }
                set { price = value; }
            }

            private double shares;

            public double Shares
            {
                get { return shares; }
                set { shares = value; }
            }
            private double value;

            public double Value
            {
                get { return this.value; }
                set
                {
                    this.value = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Value"));
                }
            }
            private string date;

            public string Date
            {
                get { return date; }
                set { date = value; }
            }

            private bool isBuy;

            public bool IsBuy
            {
                get { return isBuy; }
                set { isBuy = value;}
            }

            private double upArrow;

            public double UpArrow
            {
                get { return upArrow; }
                set { upArrow = value; }
            }
            
            private double downArrow;

            public double DownArrow
            {
                get { return downArrow; }
                set { downArrow = value; }
            }

            public double arrowWidth = 13.546;

            public double ArrowWidth
            {
                get { return arrowWidth; }
                set { arrowWidth = value; }
            }

            static int count = 0;

            public Trade()
            {
                symbol = "MSFT";
                price = DateTime.Now.Millisecond / 100.0 + 30;
                shares = 100.000;
                value = 100.00 + count++;
                date = new DateTime(2008, 1, 10).ToString("MM/dd/yyyy");
            }

            public Trade(int id, string name, string symbol, double price, double shares, double value, string date, bool isBuy)
            {
                this.id = id;
                this.name = name;
                this.symbol = symbol;
                this.price = price;
                this.shares = shares;
                this.value = value;
                this.date = date;
                this.isBuy = isBuy;
                
                // Set which direction arrow to show
                if (isBuy)
                {
                    upArrow = 1;
                    downArrow = 0;
                }
                else
                {
                    upArrow = 0;
                    downArrow = 1;
                }

                // Set width of arrow to wider if double digit id
                if (id >= 10)
                {
                    arrowWidth = 18.546;
                }
            }

        #region IComparable Members

            public int CompareTo(object obj)
            {
                System.Diagnostics.Debug.Assert(obj is Trade);
                Trade d = obj as Trade;
                if (d != null)
                {
                    if (d.Value > this.Value)
                        return 1;
                    if (d.Value < this.Value)
                        return -1;
                    else
                        return 0;
                }
                else
                    return 0;
            }

        #endregion

        #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    }

    public class SellConverter : System.Windows.Data.IValueConverter
    {
        #region IValueConverter Members

        /// <summary>
        /// Return the number of shares with brackets around it
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return "(" + value.ToString() + ")";
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
 

   


  

 
